#ifndef SHAPE_AND_RESPONSE

#define SHAPE_AND_RESPONSE
// header files for compute shape response	

#include <list>
#include <vector>
#include "sharedStructure.hpp"
#include "projector.h"
	
	
	class shapeAndResponse{
		public:
			// public functions
			// initialize member variables: 
			// h -- gabor filter radius, filter size = 2 * h +1 ;
			void initial(double *p_dim, int h);
			void release();

			void generateShapeList();
			void computeShapeScore(float **M2_maps, float *p_Mats, float *p_views, double *p_Sx, double *p_Sy, double *p_Zx, double *p_Zy, 
			float **score_maps, int** arg_max_map);
			int numShapes(){return shape_deque.size();}
			int numImages(){return n_img;};
			
			void drawShapeInCanonicalView(int *p_cluster_ind,const char* p_out_path);
			void drawShapeInDeformedView(float *p_Mats, float *p_views, double *p_Sx, 
										double *p_Sy, double *p_Zx, double *p_Zy,
										int *p_cluster_ind, int *p_arg_max_map, 
										const char *p_out_path, double *p_if_plot);
	

			projector my_projector;
		private:
			// private functions
			// convert subscript to index
			int sub2IndS2(int i_img, int i_orient, int i_angle, int i_length);
			int sub2IndS1(int i_img, int i_orient);
			int sub2IndMap(int x, int y);
			
			// functions to generate different sahpes types
			void generateCircle();
			void generateLine();
			void generateParalleLine();
			void generateTrapezoids();
			
			void equiLateralLine();
			void rightAngleLeftSideLine();
			void rightAngleRightSideLine();
			void pushParallelLineShape(line &line1, line &line2);
			void pushDeformations(int i_shape =0);

			void planeCenter(int *p_cx, int *p_cy);
			// private variables
			int n_img; // number of training images;
			int sx,sy; // plane size, height and width, in pixels
			int n_orient,n_angle,n_length;
			int h; // filter size
			std::deque<activeShape> shape_deque;
			plane current_plane;

			int max_rotation ;
		    float **R_array; /*array to save the rotation matrix for deformation*/

			int shape_layer_start[10];/*trick used to avoid repated computation*/
			line lineVertex2Line(const lineVertex &source);
			lineVertex line2lineVertex(const line &source);
	};
	
#endif
